use model_graph_types::modeling::{ClassAttribute, ValueSize, ValueType};

pub fn attribute_sql(attribute: &ClassAttribute) -> anyhow::Result<String> {
    //名称
    let column_name = attribute.name.clone();
    //字段类型
    let column_type = get_sqlite_type(&attribute.data_type, &attribute.value_size)?;
    //默认值
    let mut default_value = attribute
        .default_value
        .as_ref()
        .map_or(String::from(""), |f| f.clone());
    //注释

    let nullable = if attribute.is_nullable {
        ""
    } else {
        "NOT NULL"
    };

    if attribute.is_autoincrement {
        default_value = String::from("AUTO_INCREMENT");
    } else {
        default_value =
            get_default_value(&attribute.data_type, &attribute.value_size, default_value)?
    }

    let sql = format!(
        "`{}` {} {} {} COMMENT '{}' ",
        column_name, column_type, nullable, default_value, attribute.title
    );

    tracing::debug!("sql:{}", sql);
    Ok(sql)
}

pub fn get_sqlite_type(data_type: &ValueType, size: &ValueSize) -> anyhow::Result<String> {
    //
    match data_type {
        ValueType::String => {
            //
            match size {
                ValueSize::Tiny => Ok(String::from("VARCHAR(256)")),
                ValueSize::Medium => Ok(String::from("VARCHAR(512)")),
                ValueSize::Normal => Ok(String::from("TEXT")),
                _ => Ok(String::from("VARCHAR(512)")),
            }
        }
        ValueType::Boolean => Ok(String::from("tinyint(4)")),
        ValueType::Timestamp => Ok(String::from("TIMESTAMP")),
        ValueType::Date => Ok(String::from("int(10)")),
        ValueType::Number => Ok(String::from("int(10)")),
        ValueType::Float => Ok(String::from("decimal(10,10)")),
        _ => {
            tracing::error!("获取MySQL列类型失败:{:?}", data_type);
            Err(anyhow::anyhow!("获取MySQL列类型失败:{:?}", data_type))
        }
    }
}

pub fn get_default_value(
    data_type: &ValueType,
    size: &ValueSize,
    default_value: String,
) -> anyhow::Result<String> {
    //
    match data_type {
        ValueType::String => {
            //
            match size {
                ValueSize::Tiny => Ok(format!("DEFAULT '{}'", default_value)),
                ValueSize::Medium => Ok(format!("DEFAULT '{}'", default_value)),
                ValueSize::Normal => Ok(String::from("")),
                _ => Ok(format!("DEFAULT '{}'", default_value)),
            }
        }
        ValueType::Boolean => Ok(if &default_value == "" {
            String::from("")
        } else {
            format!("DEFAULT {}", default_value)
        }),
        ValueType::Timestamp => Ok(if &default_value == "" {
            String::from("")
        } else {
            format!("DEFAULT {}", default_value)
        }),
        ValueType::Number => Ok(format!(
            "DEFAULT {}",
            if &default_value == "" {
                String::from("0")
            } else {
                default_value
            }
        )),
        ValueType::Date => Ok(format!(
            "DEFAULT {}",
            if &default_value == "" {
                String::from("0")
            } else {
                default_value
            }
        )),
        ValueType::Float => Ok(format!(
            "DEFAULT {}",
            if &default_value == "" {
                String::from("0")
            } else {
                default_value
            }
        )),
        _ => {
            tracing::error!("获取MySQL列类型失败:{:?}", data_type);
            Err(anyhow::anyhow!("获取MySQL列类型失败:{:?}", data_type))
        }
    }
}
